package com.da.landlord;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;
import org.junit.runners.Suite;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.da.finance.DaFinanceCategory;
import com.da.finance.DaFinanceStatement;
import com.da.finance.DaFinanceStatementService;
import com.googlecode.cswish.annotation.Rest;
import com.googlecode.cswish.exception.ApplicationException;
import com.googlecode.cswish.model.PageInfo;
import com.googlecode.cswish.model.Reference;
import com.googlecode.cswish.oosearch.Condition;
import com.googlecode.cswish.oosearch.QLInfo;
import com.googlecode.cswish.struts.ServletRedirectResult;
import com.googlecode.cswish.struts.spring.GenericService;
import com.googlecode.cswish.struts.spring.ObjectFactory;
import com.googlecode.cswish.util.bean.ModelUtil;
import com.opensymphony.xwork2.Result;
import com.ra.landlord.BankCard;
import com.ra.landlord.Building;
import com.ra.landlord.BuildingService;
import com.ra.util.Address;
import com.ra.util.AddressCode;

/**
 * 业主管理service
 * @author Peter Z
 *
 */
@Service
public class DaOwnerService {

	
	@Resource
	private GenericService genericService;
	@Resource
	private DaFinanceStatementService daFinanceStatementService;
	
	@Resource
	private BuildingService buildingService;
	
	@Resource
	private DaSuiteService daSuiteService;
	
	@Resource
	private ObjectFactory objectFactory;
	
	private static final Log logger = LogFactory.getLog(DaOwnerService.class);
	
	@Rest(type = "search")
	public PageInfo<DaOwner> search1(DaOwner model,int start,int limit,String sort, String dir, boolean oldSearch, Reference<QLInfo> qlInfoRef){
		
		PageInfo<DaOwner> pageInfo = genericService.search(model, start, limit, sort, dir, oldSearch, qlInfoRef);
		//下次交租时间  下次的交租金额  距合约到期?天   由收租时来更变下次交租时间 和下次交租金额。
		
		//from daowneragreement a where a.ownerid
		
		return pageInfo;
	}
	
	
	@Rest(type = "search")
	public PageInfo<DaOwnerAgreement> search(String keywords,String dayNum,Integer agreementState, Reference<QLInfo> qlInfoRef,int pageIndex,int pageSize){
		
		QLInfo qlInfo = new QLInfo();
		
		String agreQL = " from "+DaOwnerAgreement.class.getName()+" a  where 1=1 ";
		
		
		if(StringUtils.isNotEmpty(keywords)){
			agreQL += " and (a.relateSuiteName like ? or a.owner.name like ? )";
			qlInfo.addParam("%"+keywords+"%");
			qlInfo.addParam("%"+keywords+"%");
		}
		
		if(StringUtils.isNotEmpty(dayNum)){
			try{
				int num = Integer.parseInt(dayNum);
				Calendar c = Calendar.getInstance();
				c.add(Calendar.DAY_OF_MONTH, num);
				Date comparDate = c.getTime();
				
				agreQL+=" and a.rentEndDate < ? ";
				qlInfo.addParam(comparDate);
			}catch(Exception e){
				//...
			}
		}
		

		if(agreementState!=null){
			if(agreementState == 1){
				agreQL+= " and a.rentEndDate > ?";
			}else{
				agreQL+= " and a.rentEndDate < ?";
			}
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			String comparDateStr = sdf.format(new Date());
			try {
				qlInfo.addParam(sdf.parse(comparDateStr));
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		
		qlInfo.setQl(agreQL);
		int totalCount = genericService.getCount(qlInfo, false);
		
		PageInfo<DaOwnerAgreement> pageInfo =  genericService.searchByQl(qlInfo);
		
		pageInfo.setPageSize(pageSize);
		pageInfo.setTotalCount(totalCount);
		
		return pageInfo;
	}
	
	
	/**
	 * 交租
	 */
	public DaOwnerAgreement _pay(DaOwnerAgreement model){
		model = genericService.view(model);
		return model;
	}
	
	public Result pay(DaOwnerAgreement model,BigDecimal money){
		DaOwnerAgreement oldModel = genericService.load(model);
		oldModel.setNextPayDate(model.getNextPayDate());
		genericService.merge(oldModel);
		
		if(oldModel.getType().equals(DaOwnerAgreement.ISSUITE)){
			Integer relateSuiteId = oldModel.getRelateSuiteId();
			DaSuite suite = new DaSuite();
			suite.setId(relateSuiteId);
			suite = genericService.load(suite);
			DaRoom room = suite.getRooms().get(0);
			daFinanceStatementService.addInternal(room, money, DaFinanceCategory.FINANCE_CATEGORY_OWNER_RENT, new Date(), DaFinanceStatement.TRADE_TYPE_CRASH, "向业主交房租");
		}
		Result result = new ServletRedirectResult("/da/landlord/daOwner.search.html");
		objectFactory.autoWireBean(result);
		return result;
	}
	
	/**
	 * 终止合约
	 * @param model
	 * @return
	 */
	public DaOwnerAgreement _stopAgreement(DaOwnerAgreement model){
		model = genericService.view(model);
		return model;
	}
	
	public Result stopAgreement(DaOwnerAgreement model,BigDecimal money){
		DaOwnerAgreement oldModel = genericService.load(model);
		oldModel.setAgreementState(false);//合约终止
		genericService.merge(oldModel);
		
		if(oldModel.getType().equals(DaOwnerAgreement.ISSUITE)){
			DaSuite suite = new DaSuite();
			suite.setId(oldModel.getRelateSuiteId());
			suite = genericService.load(suite);
			DaRoom daRoom = suite.getRooms().get(0);
			daFinanceStatementService.addInternal(daRoom, money, DaFinanceCategory.FINANCE_CATEGORY_OWNER_UNRENT, new Date(), DaFinanceStatement.TRADE_TYPE_CRASH, "向业主退房退租");
		}else{
			//集中式的财务流水  一栋楼的情况
		}
		
		Result result = new ServletRedirectResult("/da/landlord/daOwner.search.html");
		objectFactory.autoWireBean(result);
		return result;
	}
	
	
	/**
	 * 获取所有的业主信息
	 * @return
	 */
	@Rest(type = "search")
	public List<DaOwner> searchAll(){
		return genericService.searchByModel(new DaOwner(),Condition.DEFAULT,false,false).getData();
	}
	
	/**
	 * 进入新增或是修改业主页面
	 * @param model
	 * @return
	 */
	@Rest(type = "update")
	public DaOwnerAgreement _update( DaOwnerAgreement model ){
		if(model.getId() != null){
			model =  genericService.view( model );
		}
		return model;
	}
	
	
	/**
	 * 进入业主浏览页面
	 * @param model
	 * @return
	 */
	@Rest(type = "update")
	public DaOwner view( DaOwner model ){
		if(model.getId() != null){
			model =  genericService.view( model );
		}
		return model;
	}
	
	
	
	
	/**
	 * 新增业主
	 * @param model
	 * @return
	 */
	@Rest(type = "add")
	@Transactional
	public Result addDaOwner( DaOwner model ){
		//每次添加都是添加一个业主，查看这个业主是否存，如果存在，就使用原来的业主，不存在，就新加入一个业主。
		
		if( !isUpdate( model ) ){
			DaOwnerAgreement agreement = model.getOwnerAgreement().get(0);
			setAgreementParm(agreement);
			model = genericService.merge( model );
			//addInternal(model,true);
		}
		
		Result result = new ServletRedirectResult( "/da/landlord/daOwner.search.html" );
		ObjectFactory.getInstance().autoWireBean(result);
		return result;
	}

	/**
	 * 添加业主合约
	 * @param model
	 * @return
	 */
	@Rest(type = "add")
	@Transactional
	public Result addOwnerAgreement( DaOwnerAgreement model ){
		//每次添加都是添加一个业主，查看这个业主是否存，如果存在，就使用原来的业主，不存在，就新加入一个业主。
		
		if( !isUpdateAgreeMent( model ) ){
			DaOwnerAgreement agreement = model;
			setAgreementParm(agreement);
			model = genericService.add( model );
			DaOwner owner = model.getOwner();
			owner = genericService.load(owner);
			addInternal(model,true);
		}
		
		Result result = new ServletRedirectResult( "/da/landlord/daOwner.search.html" );
		ObjectFactory.getInstance().autoWireBean(result);
		return result;
	}
	
	private boolean isUpdateAgreeMent(DaOwnerAgreement model){
		if(model.getId()==null)return false;
		DaOwnerAgreement oldModel = genericService.load(model);
		DaOwner oldOwner = oldModel.getOwner();
		ModelUtil.deepCopy( model.getOwner(), oldOwner, Arrays.asList("name", "gender", "addrDsc", "phone", "qq", "email", "idCard", "photoFileName","mark") );
		
		ModelUtil.deepCopy( model, oldModel, Arrays.asList("agreementNum", "advanceNum", "deposit", "rentPay", "depositNum", "payNum", "rentPeriod", "rentEndDate","type","relateSuiteName","relateSuiteId") );
		
		List<BankCard> cards = oldOwner.getBankCards();
		if( null== cards )cards = new ArrayList<BankCard>();
		
		if(cards.size()<=0){
			cards.add(new BankCard());
		}
		
		BankCard newCard =null;
		if(model.getOwner().getBankCards()==null||model.getOwner().getBankCards().size()<=0){
			newCard = new BankCard();
		}else{
			newCard =  model.getOwner().getBankCards().get(0);
		}
		
		cards.get(0).setName(newCard.getName());
		cards.get(0).setIssuing(newCard.getIssuing());
		cards.get(0).setCardNumber(newCard.getCardNumber());
		oldOwner.setBankCards(cards);
		oldModel.setOwner(oldOwner);
		
		if(model.getRentEndDate() == null){
			Calendar c = Calendar.getInstance();
			c.setTime(oldModel.getRentBeginDate());
			c.add(Calendar.YEAR, 1);
			oldModel.setRentEndDate(c.getTime());
		}
		
		
		genericService.merge(oldModel);
		
		return true;
	}
	
	
	/**
	 * 添加财务流水
	 * @param model
	 */
	@Transactional
	private void addInternal(DaOwnerAgreement agreement,boolean addDeposit) {
		
		Integer type= agreement.getType();
		
		if(type.equals(DaOwnerAgreement.ISBUILDING)){
			//集中式的暂不添加财务流水.
		}else{
			Integer suiteId = agreement.getRelateSuiteId();
			DaSuite suite = new DaSuite();
			suite.setId(suiteId);;
			suite = genericService.load(suite);
			DaRoom room = suite.getRooms().get(0);
			
			BigDecimal rentPay = agreement.getRentPay();//租金
			if(agreement.getPayNum() != null){
				rentPay = rentPay.multiply( new BigDecimal(agreement.getPayNum()) );
			}
			BigDecimal deposit = agreement.getDeposit();
			
			//付几 几个月一付
			daFinanceStatementService.addInternal(room, rentPay, DaFinanceCategory.FINANCE_CATEGORY_OWNER_RENT, new Date(), DaFinanceStatement.TRADE_TYPE_CRASH, "向业主交租");
			
			if(deposit != null && addDeposit ){
				daFinanceStatementService.addInternal(room, deposit, DaFinanceCategory.FINANCE_CATEGORY_OWNER_DEPOSIT, new Date(), DaFinanceStatement.TRADE_TYPE_CRASH, "向业主交押金");
			}
			
		}
		
		
		
		
	}

	private void setAgreementParm(DaOwnerAgreement agreement) {
		agreement.setAgreementState(true);
		
		if(agreement.getRentEndDate() == null ){
			Calendar c = Calendar.getInstance();
			c.setTime(agreement.getRentBeginDate());
			c.add(Calendar.YEAR, 1);
			agreement.setRentEndDate(c.getTime());
		}
		agreement.setSignDate( Calendar.getInstance().getTime());
		//设置下次交租时间 及下次交租金额
		Calendar c =  Calendar.getInstance();
		c.setTime(agreement.getRentBeginDate());
		c.add(Calendar.MONTH, agreement.getPayNum());
		agreement.setNextPayDate(c.getTime());
		BigDecimal nextCount = agreement.getRentPay().multiply( new BigDecimal(agreement.getPayNum()) );
		agreement.setNextPayCount(nextCount);
		
		
		//判断业主是否已存在
		DaOwner owner = agreement.getOwner();
		QLInfo qlInfo = new QLInfo();
		String ql = "select a from "+DaOwner.class.getName()+" a  where 1=1";
		ql+= " and a.phone = ? and a.name = ?";
		qlInfo.addParam(owner.getPhone());
		qlInfo.addParam(owner.getName());
		qlInfo.setQl(ql);
		PageInfo<DaOwner> searchByQl = genericService.searchByQl(qlInfo);
		List<DaOwner> data = searchByQl.getData();
		if(data.size() > 0){
			DaOwner oldOwner = data.get(0);
			ModelUtil.deepCopy( owner, oldOwner, Arrays.asList("name", "gender", "addrDsc", "phone", "qq", "email", "idCard", "photoFileName","mark") );
			
			//更新银行卡号
			List<BankCard> cards = oldOwner.getBankCards();
			if( null== cards )cards = new ArrayList<BankCard>();
			
			if(cards.size()<=0){
				cards.add(new BankCard());
			}
			
			BankCard newCard =null;
			if(owner.getBankCards()==null||owner.getBankCards().size()<=0){
				newCard = new BankCard();
			}else{
				newCard =  owner.getBankCards().get(0);
			}
			
			//只修改第一个
			cards.get(0).setName(newCard.getName());
			cards.get(0).setIssuing(newCard.getIssuing());
			cards.get(0).setCardNumber(newCard.getCardNumber());
			oldOwner.setBankCards(cards);
			
			//取以前的
			agreement.setOwner(oldOwner);
		}
	}
	
	
	/**
	 * 修改业主
	 * @param model
	 * @return
	 */
	public boolean isUpdate( DaOwner model ){
		
		if( model.getId() == null ){
			return false;
		}
		
		DaOwner oldObject = genericService.load( model );
		
		if( oldObject == null ){
			logger.error( "不存在要修改的对象" );
			throw new ApplicationException("不存丰修改的对象!");
		}
		ModelUtil.deepCopy( model, oldObject, Arrays.asList("name", "gender", "addrDsc", "phone", "qq", "email", "idCard", "photoFileName","mark") );
		
		setUpdateParm(model, oldObject);
		//修改银行卡号
		genericService.merge( oldObject );
		
		return true;
	}

	private void setUpdateParm(DaOwner model, DaOwner oldObject) {
		List<BankCard> cards = oldObject.getBankCards();
		if( null== cards )cards = new ArrayList<BankCard>();
		
		if(cards.size()<=0){
			cards.add(new BankCard());
		}
		
		BankCard newCard =null;
		if(model.getBankCards()==null||model.getBankCards().size()<=0){
			newCard = new BankCard();
		}else{
			newCard =  model.getBankCards().get(0);
		}
		
		cards.get(0).setName(newCard.getName());
		cards.get(0).setIssuing(newCard.getIssuing());
		cards.get(0).setCardNumber(newCard.getCardNumber());
		
		DaOwnerAgreement agreement =  model.getOwnerAgreement().get(0);
		List<DaOwnerAgreement> agreements = oldObject.getOwnerAgreement();
		agreements.get(0).setAgreementNum(agreement.getAgreementNum());
		agreements.get(0).setAdvanceNum(agreement.getAdvanceNum());
		agreements.get(0).setDeposit(agreement.getDeposit());
		agreements.get(0).setRentPay(agreement.getRentPay());
		agreements.get(0).setDepositNum(agreement.getDepositNum());
		agreements.get(0).setPayNum(agreement.getPayNum());
		agreements.get(0).setRentPeriod(agreement.getRentPeriod());
		//agreements.get(0).setRentBeginDate(agreement.getRentBeginDate()); //不能改开始日期
		agreements.get(0).setRentEndDate(agreement.getRentEndDate());
		//setAddress(agreement.getSuite());
		
		
		if(agreement.getRentEndDate() == null){
			Calendar c = Calendar.getInstance();
			c.setTime(agreement.getRentBeginDate());
			c.add(Calendar.YEAR, 1);
			agreements.get(0).setRentEndDate(c.getTime());
		}
		
		oldObject.setBankCards(cards);
		
	}
	
	
	
	/**
	 * 删除业主
	 * @param model
	 * @return
	 */
	@Rest(type = "delete")
	public boolean delete( List<DaOwnerAgreement> model ){
		
		boolean result = true;
		for (DaOwnerAgreement daOwnerAgreement : model) {
			DaOwnerAgreement view = genericService.view(daOwnerAgreement);
			DaOwner owner = view.getOwner();
			genericService.delete(view);
			canDeleteOwner(owner);
		}
		return result;
	}
	
	@Transactional
	private void canDeleteOwner(DaOwner owner){
		String ql = "select a from "+DaOwner.class.getName()+ " a where 1=1";
		ql += " and a.id = ?";
		QLInfo qlInfo = new QLInfo();
		qlInfo.addParam(owner.getId());
		qlInfo.setQl(ql);;
		PageInfo<DaOwner> searchByQl = genericService.searchByQl(qlInfo);
		List<DaOwner> data = searchByQl.getData();
		if( data.size() == 0 ){
			genericService.delete(owner);
		}
		return ;
	}
	
	

	/**
	 * 为房源绑定业主
	 * @param suite
	 * @param owner
	 * @return
	 */
	@Rest(type = "update")
	public boolean bandingOwner(DaSuite suite,DaOwner owner){
		if(null != suite && suite.getId() != null  && null != owner && null != owner.getId()){
			suite = genericService.load(suite);
			owner = genericService.load(owner,false);
			suite.setDaOwner(owner);
			genericService.merge(owner);
			return true;
		}else{
			return false;
		}
	}
	

	/**
	 * 获取没有绑定业主的所有房源
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@Rest(type = "search")
	public PageInfo<DaSuite> noOwnerSuites(){
		QLInfo ql = new QLInfo();
		ql.setQl( "FROM DaSuite AS a WHERE a.daOwner IS NULL" );
		 return genericService.searchByQl( ql );
	}
	
	
	/**
	 * 返回上传文件的位置
	 * */
	@Rest(type = "search")
    public String getSavePath() throws Exception{
        return ServletActionContext.getServletContext().getRealPath("site/da/upload/DaOwner/"); 
    }
	
	@Rest(type="search")
	public List<DaOwnerAllSuiteVO> getAllSuites(){
		ArrayList<DaOwnerAllSuiteVO> returnList = new ArrayList<DaOwnerAllSuiteVO>();
		
		List<DaSuite> ownerSuites = daSuiteService.searchDaSuite();
		if(ownerSuites!=null && ownerSuites.size()>0){
			for (DaSuite daSuite : ownerSuites) {
				//去除旧数据中无效的房源
				if(daSuite.getCreateDate()==null && daSuite.getArea()==null && daSuite.getRoomCount()==null){
					continue;
				}
				DaOwnerAllSuiteVO vo = new DaOwnerAllSuiteVO();
				vo.setId(daSuite.getId());
				vo.setType(DaOwnerAllSuiteVO.ISSUITE);
				vo.setName(daSuite.getName()+"(普通房源)");
				returnList.add(vo);
			}
		}
		
		List<Building> ownerBuildings = buildingService.searchBuilding();
		if(ownerBuildings!=null && ownerBuildings.size() >0 ){
			for (Building building : ownerBuildings) {
				DaOwnerAllSuiteVO vo = new DaOwnerAllSuiteVO();
				vo.setId(building.getId());
				vo.setType(DaOwnerAllSuiteVO.ISBUILDING);
				vo.setName(building.getName()+"(楼房)");
				returnList.add(vo);
			}
		}
		return returnList;
		
	}
	
}
